﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;

namespace Carbon.Web.Forms.jQueryForms
{
    public class CheckBoxListEditor : CheckBoxList, IEditor
    {
		#region Classes (1)
		private class Parallel
        {
			#region Static Methods (2)
			public static void Iterate<T, T2>(IEnumerable first, IEnumerable second, Action<T, T2> doAction)
                {
                    Iterate<T, T2>(first.Cast<T>(), second.Cast<T2>(), doAction);
                }

			public static void Iterate<TSequence1, TSequence2>(IEnumerable<TSequence1> first, IEnumerable<TSequence2> second, Action<TSequence1, TSequence2> action)
                {
                    if (first == null) throw new NullReferenceException("first");
                    if (second == null) throw new NullReferenceException("second");

                    IEnumerator<TSequence1> firstEnumerator = first.GetEnumerator();
                    IEnumerator<TSequence2> secondEnumerator = second.GetEnumerator();

                    if ((first.Count() == second.Count()) == false) throw new InvalidOperationException("(first.Count() == second.Count()) == false");

                    while (firstEnumerator.MoveNext() && secondEnumerator.MoveNext())
                    {
                        action(firstEnumerator.Current, secondEnumerator.Current);
                    }
                }
			#endregion
        }
		#endregion

		#region Fields (2)
		private ICheckBoxListItemCollection m_Items = default(ICheckBoxListItemCollection);

		private ListEditor m_Parent = default(ListEditor);
		#endregion

		#region Properties (5)
		public bool IsNull
        {
            get
            {
                return false;
            }
        }
		public new ICheckBoxListItemCollection Items
        {
            get
            {
                return m_Items;
            }
            private set
            {
                m_Items = value; base.Items.Clear();
                foreach (IListEditorItem item in Items)
                {
                    base.Items.Add(new ListItem(Items.GetDisplayName(item.Data), string.Empty) { Selected = item.Selected });
                }
            }
        }
		public new ListEditor Parent
        {
            get
            {
                return m_Parent;
            }
        }
		public bool ReadOnly
        {
            get
            {
                return !this.Enabled;
            }
            set
            {
                this.Enabled = !value;
            }
        }
		public object Value
        {
            get
            {
                if (!this.Parent.AutoPostback)
                {
                    ReturnDataToModel();
                }

                return Items;
            }
            set
            {
                Items = (ICheckBoxListItemCollection)value;
            }
        }
		#endregion

		#region Constructors (1)
		public CheckBoxListEditor(ICheckBoxListItemCollection items, ListEditor parent)
            : base()
        {
            if (items == null) throw new ArgumentNullException("items");

             if (parent == null)  throw new NullReferenceException("parent");

            this.m_Parent = parent;
            this.Items = items;

            this.ReadOnly = Parent.ReadOnly;
            this.AutoPostBack = Parent.AutoPostback;

            this.CssClass = Parent.CssClass;

            this.SelectedIndexChanged += new EventHandler(CheckBoxListEditor_SelectedIndexChanged);
        }
		#endregion

		#region ASP Processing

		public override void RenderControl(System.Web.UI.HtmlTextWriter writer)
        {
            SimpleEditor.RenderBoxes(writer, false, false, string.Empty, () =>
                {
                    base.RenderControl(writer);
                });
        }

		#endregion

		#region Methods (1)

		private void ReturnDataToModel()
        {  
            Parallel.Iterate<IListEditorItem, ListItem>((IEnumerable)Items, (IEnumerable)base.Items, (dataItem, uiItem) =>
                    {
                        dataItem.Selected = uiItem.Selected;
                    });
        }

		#endregion

		#region Event Handlers (1)

		void CheckBoxListEditor_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.Parent.AutoPostback)
            {
                ReturnDataToModel();
                this.RaiseBubbleEvent(this, new UpdateModelEventArgs());
            }
        }

		#endregion
    }
}
